package com.gzhryc.system;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.data.TreeUtils;
import com.gzhryc.common.data.TreeUtils.ConvertListen;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.xml.XmlTools;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.system.dao.MenuDao;
import com.gzhryc.system.dao.db.Menu;
import com.gzhryc.system.dao.enums.MenuEnum;
import com.gzhryc.system.dao.models.MenuEntity;
import com.gzhryc.system.dto.MenuConfig;
import com.gzhryc.system.dto.MenuData;
import com.gzhryc.system.dto.MenuSearch;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.*;

public class MenuService {

	static Logger log = Logger.getLogger(MenuService.class);

	public static MenuService self() {
		return MultiDBTools.getService(MenuService.class, true);
	}

	public static MenuService self(String jdbcKey) {
		return MultiDBTools.getService(jdbcKey, MenuService.class, true);
	}

	MenuDao menuDao;

	public MenuService(String jdbcKey) {
		this.menuDao = new MenuDao(jdbcKey);
	}

	public List<Menu> findBySearch(MenuSearch search, Integer pageNo, Integer pageLimit) {
		Conditions condition = new Conditions(Menu.class);
		condition.and().likeBoth("name", search.getName());
		condition.and().is("parentId", search.getParentId());
		condition.and().in("type", search.getTypes());
		condition.and().is("link", search.getLink());
		condition.and().is("permission", search.getPermission());
		condition.asc("parentId");
		condition.asc("priority");
		condition.asc("id");
		try {
			return menuDao.findByCondition(condition, pageNo, pageLimit);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public Long countBySearch(MenuSearch search) {
		Conditions condition = new Conditions(Menu.class);
		condition.and().likeBoth("name", search.getName());
		condition.and().is("parentId", search.getParentId());
		condition.and().in("type", search.getTypes());
		condition.and().is("link", search.getLink());
		condition.and().is("permission", search.getPermission());
		try {
			return menuDao.count(condition);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return 0L;
	}

	public List<Menu> findBySearchAndNotParent(MenuSearch search, Integer pageNo, Integer pageLimit) {
		Conditions condition = new Conditions(Menu.class);
		if (search.getParentId() == null) {
			condition.and().isNull("parentId");
		} else {
			condition.and().is("parentId", search.getParentId());
		}
		condition.and().likeBoth("name", search.getName());
		condition.asc("priority");
		condition.asc("id");
		try {
			return menuDao.findByCondition(condition, pageNo, pageLimit);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<Menu> findAll(){
		try {
			return menuDao.findAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<Menu> findAllParent(){
		Conditions condition = new Conditions(Menu.class);
		condition.and().isNull("parentId").or().is("parentId",0);
		condition.asc("id");

		try {
			return menuDao.findByCondition(condition);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<Menu> findAllChild(List<Long> parentIds){
		if(parentIds != null && parentIds.size() > 0) {
			Conditions condition = new Conditions(Menu.class);
			condition.and().in("parentId", parentIds);
			try {
				return menuDao.findByCondition(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public List<Menu> findAllChild(Long parentId){
		if(parentId != null) {
			Conditions condition = new Conditions(Menu.class);
			condition.and().is("parentId", parentId);
			condition.asc("id");
			try {
				return menuDao.findByCondition(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public List<Menu> findByParentAndType(Long parentId, Integer type) {
		if (type != null) {
			Conditions condition = new Conditions(Menu.class);
			if (parentId == null) {
				condition.and().isNull("parentId");
			} else {
				condition.and().is("parentId", parentId);
			}
			condition.and().is("type", type);
			try {
				return menuDao.findByCondition(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public Menu getById(Long id) {
		try {
			return menuDao.getById(id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public MenuEntity getEntityById(Long id) {
		try {
			return menuDao.getEntityById(id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public Menu getByParentIdAndName(Long parentId, String name) {
		if (StringUtils.isNotBlank(name)) {
			Conditions condition = new Conditions(Menu.class);
			condition.and().is("parentId", parentId);
			condition.and().is("name", name);
			try {
				return menuDao.get(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public Menu getByParentIdAndLink(Long parentId, String link) {
		if (StringUtils.isNotBlank(link)) {
			Conditions condition = new Conditions(Menu.class);
			condition.and().is("parentId", parentId);
			condition.and().is("link", link);
			try {
				return menuDao.get(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public Menu getByParentIdAndPermission(Long parentId, String permission) {
		if (StringUtils.isNotBlank(permission)) {
			Conditions condition = new Conditions(Menu.class);
			condition.and().is("parentId", parentId);
			condition.and().is("permission", permission);
			try {
				return menuDao.get(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public Menu getByRootAndName(String name) {
		if (StringUtils.isNotBlank(name)) {
			Conditions condition = new Conditions(Menu.class);
			condition.and().isNull("parentId").or().is("parentId", 0);
			condition.and().is("name", name);
			try {
				return menuDao.get(condition);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public synchronized boolean save(Menu menu) throws LogicException {
		if (menu.getType() == null) {
			if (StringUtils.isNotBlank(menu.getLink())) {
				menu.setType(MenuEnum.Type.PathAuthorization.index());
			} else if (StringUtils.isNotBlank(menu.getPermission())) {
				menu.setType(MenuEnum.Type.FunAuthorization.index());
			} else {
				menu.setType(MenuEnum.Type.GroupAuthorization.index());
			}
		}

		if (MenuEnum.Type.PathAuthorization.index().equals(menu.getType())) {
			if (StringUtils.isBlank(menu.getLink())) {
				throw new LogicException("请填写访问路径");
			}
			Menu entity = this.getByParentIdAndLink(menu.getParentId(), menu.getLink());
			if (entity != null) {
				menu.setId(entity.getId());
			}
		} else if (MenuEnum.Type.FunAuthorization.index().equals(menu.getType())) {
			if (StringUtils.isBlank(menu.getPermission())) {
				throw new LogicException("请填写权限信息");
			}
			Menu entity = this.getByParentIdAndPermission(menu.getParentId(), menu.getPermission());
			if (entity != null) {
				menu.setId(entity.getId());
			}
		} else {
			Menu entity = this.getByParentIdAndName(menu.getParentId(), menu.getName());
			if (entity != null) {
				menu.setId(entity.getId());
			}
		}

		if (menu.getId() != null) {
			try {
				if (menuDao.updateNotNull(menu,"link","icon","permission") > 0) {
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		} else {
			try {
				if (menu.getIsLeaf() == null) {
					menu.setIsLeaf(true);
				}
				if (menu.getPriority() == null) {
					menu.setPriority(10);
				}
				menu.setCreateDate(new Date());
				if (menuDao.insert(menu) > 0) {
					if (menu.getParentId() != null) {
						updateLeaf(menu.getParentId(), false);
					}
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return false;
	}

	public synchronized boolean add(Menu menu) throws LogicException {
		if (menu.getType() == null) {
			if (StringUtils.isNotBlank(menu.getLink())) {
				menu.setType(MenuEnum.Type.PathAuthorization.index());
			} else {
				menu.setType(MenuEnum.Type.GroupAuthorization.index());
			}
		}
		if (!MenuEnum.Type.GroupAuthorization.index().equals(menu.getType())) {
			if (StringUtils.isBlank(menu.getLink())) {
				throw new LogicException("请填写访问路径");
			}
		}
		if (MenuEnum.Type.FunAuthorization.index().equals(menu.getType())) {
			if (StringUtils.isBlank(menu.getPermission())) {
				throw new LogicException("请填写权限信息");
			}
		}
		Menu entity = getByParentIdAndName(menu.getParentId(), menu.getName());
		if (entity != null) {
			throw new LogicException("菜单重名");
		}
		try {
			if (menu.getIsLeaf() == null) {
				menu.setIsLeaf(true);
			}
			if (menu.getPriority() == null) {
				menu.setPriority(10);
			}
			menu.setCreateDate(new Date());
			if (menuDao.insert(menu) > 0) {
				if (menu.getParentId() != null) {
					updateLeaf(menu.getParentId(), false);
				}
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 修改菜单
	 * 
	 * @param menu
	 * @return
	 * @throws LogicException
	 */
	public synchronized boolean update(Menu menu) throws LogicException {
		try {
			Menu entity = getByParentIdAndName(menu.getParentId(), menu.getName());
			if (entity != null && !entity.getId().equals(menu.getId())) {
				throw new LogicException("菜单重名");
			}
			if (entity == null) {
				entity = menuDao.getById(menu.getId());
			}

			if (MenuEnum.Type.FunAuthorization.index().equals(menu.getType())) {
				if (StringUtils.isBlank(menu.getPermission()) && StringUtils.isBlank(entity.getPermission())) {
					throw new LogicException("请填写权限信息");
				}
			}
			boolean isNewParent = eq(entity.getParentId(), menu.getParentId());
			if (isNewParent) {
				// 检查旧的父菜单是否需要修改Leaf属性
				if (entity.getParentId() != null) {
					Long total = countBySearch(new MenuSearch(entity.getParentId()));
					if (total == null || total == 0) {
						updateLeaf(entity.getParentId(), true);
					}
				}
			}
			if (menuDao.updateNotNull(menu,"link","icon","permission") > 0) {
				if (isNewParent && menu.getParentId() != null) {
					updateLeaf(menu.getParentId(), false);
				}
				return true;
			}
		} catch (SQLException e) {
			log.error(e.getMessage(),e);
		}
		return false;
	}

	private boolean eq(Long oldId, Long newId) {
		if (oldId != null) {
			return oldId.equals(newId);
		} else if (newId == null) {
			return true;
		}
		return false;
	}

	/**
	 * 修改Leaf属性
	 * 
	 * @param id
	 * @param leaf
	 * @return
	 */
	public boolean updateLeaf(Long id, Boolean leaf) {
		Menu menu = new Menu();
		menu.setId(id);
		menu.setIsLeaf(leaf);
		try {
			if (menuDao.updateNotNull(menu) > 0) {
				return true;
			}
		} catch (SQLException e) {
			log.error(e.getMessage(),e);
		}
		return false;
	}

	/**
	 * 根据ID删除菜单
	 * 
	 * @param id
	 * @return
	 * @throws LogicException
	 */
	public boolean deleteById(Long id) throws LogicException {
		Long total = countBySearch(new MenuSearch(id));
		if (total != null && total > 0) {
			throw new LogicException("请先删除该菜单的子菜单");
		}

		JdbcSession.begin();
		try {
			Menu menu = menuDao.getById(id);
			if (menuDao.deleteById(id) > 0) {
				//删除角色配置
				if(RoleService.self().delByMenuId(id)) {
					if (menu.getParentId() != null) {
						MenuSearch search = new MenuSearch();
						search.setParentId(menu.getParentId());
						if (countBySearch(search) == 0) {
							Menu updateEntity = new Menu();
							updateEntity.setId(menu.getParentId());
							updateEntity.setIsLeaf(true);
							menuDao.updateNotNull(updateEntity);
						}
					}

					JdbcSession.commit();
					return true;
				}
			}
		} catch (SQLException e) {
			log.error(e.getMessage(),e);
		} finally {
			JdbcSession.end();
		}
		return false;
	}

	public List<Menu> findByRoleId(Long roleId) {
		if (roleId != null) {
			try {
				return menuDao.findByRoleId(roleId);
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return null;
	}

	public List<Menu> findByManagerId(Long managerId) {
		if (managerId != null) {
			try {
				return menuDao.findByManagerId(managerId);
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return null;
	}

	public List<Menu> findByManagerIdAndPermission(Long managerId, String permission) {
		if (managerId != null && StringUtils.isNotBlank(permission)) {
			try {
				return menuDao.findByManagerIdAndPermission(managerId, permission);
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return null;
	}

	public boolean hasByManagerIdAndPermission(Long managerId, String permission) {
		if (managerId != null && StringUtils.isNotBlank(permission)) {
			try {
				return menuDao.countByManagerIdAndPermission(managerId, permission) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	public boolean hasByManagerIdAndPermission(Long managerId, String[] permission) {
		if (managerId != null && permission != null && permission.length > 0) {
			try {
				return menuDao.countByManagerIdAndPermission(managerId, permission) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	public List<MenuData> findMenuDataByManagerId(Long managerId) {
		List<Menu> menus = findByManagerId(managerId);
		List<MenuData> menuData = TreeUtils.byTree(menus, new ConvertListen<Menu, MenuData>() {
			public MenuData change(Menu parent, Menu obj) {
				return ClassTools.copy(new MenuData(), obj);
			}
		});
		return menuData;
	}

	public List<MenuData> readMenuConfig(InputStream inStream) {
		if (inStream != null) {
			MenuConfig config = XmlTools.changToObject(inStream, MenuConfig.class, false);
			if (config != null) {
				log.info("初始化菜单：" + JsonTools.toJson(config));
				if (config.getMenus() != null && config.getMenus().size() > 0) {
					List<MenuData> result = new ArrayList<>();
					for (MenuConfig.Item item : config.getMenus()) {
						MenuData menu = ClassTools.copy(new MenuData(), item);
						// 添加子菜单
						if (item.getChildren() != null && item.getChildren().size() > 0) {
							menu.setChildren(readMenuConfig(item.getChildren()));
						}
						result.add(menu);
					}
					return result;
				}
			}
		}
		return null;
	}

	public List<MenuData> readMenuConfig(String filePath) {
		File file = new File(filePath);
		InputStream inStream = null;
		if (file.exists()) {
			try {
				inStream = new FileInputStream(file);
				return readMenuConfig(inStream);
			} catch (FileNotFoundException e) {
				log.error(e.getMessage(),e);
			}
		}
		return null;
	}

	private List<MenuData> readMenuConfig(List<MenuConfig.Item> children) {
		List<MenuData> result = new ArrayList<>();
		for (MenuConfig.Item item : children) {
			MenuData menu = ClassTools.copy(new MenuData(), item);
			// 添加子菜单
			if (item.getChildren() != null && item.getChildren().size() > 0) {
				menu.setChildren(readMenuConfig(item.getChildren()));
			}
			result.add(menu);
		}
		return result;
	}

	public List<MenuData> merge(List<MenuData> menuDataList,List<MenuData> addMenuDataList){
		if(addMenuDataList != null && addMenuDataList != null){
			for(MenuData addMenuData :addMenuDataList){
				MenuData menuData = null;
				for(MenuData item : menuDataList){
					//修改名称或访问路径都可以
					if (item.getName().equals(addMenuData.getName())) {
						menuData = item;
						break;
					}
					if(addMenuData.getType() != null && addMenuData.getType() > 0) {
						if (StringTools.isNotBlank(addMenuData.getLink()) && addMenuData.getLink().equals(item.getLink())) {
							menuData = item;
							break;
						}
					}
				}

				if(menuData != null){
					if(addMenuData.getChildren() != null && addMenuData.getChildren().size() > 0){
						List<MenuData> children = menuData.getChildren();
						if(children == null){
							children = new ArrayList<>();
						}
						//合并子菜单
						menuData.setChildren(merge(children,addMenuData.getChildren()));
					}
				}else{
					menuDataList.add(addMenuData);
				}
			}
		}
		return menuDataList;
	}

	public void refreshMenu(List<MenuData> menuData, boolean canDel) {
		if (menuData != null && menuData.size() > 0) {
			List<Menu> menuList = this.findAllParent();
			if (menuList != null && menuList.size() > 0) {
				log.info(menuDao.getJdbcKey()+ "数据库根节点数：{{0}}，需要更新的根节点数：{{1}}",menuList.size(),menuData.size());

				for (MenuData item : menuData) {
					int index = -1;
					Menu entity = null;
					for (int i = 0; i < menuList.size(); i++) {
						Menu menu = menuList.get(i);
						//修改名称或访问路径都可以
						if (item.getName().equals(menu.getName())) {
							index = i;
							entity = menu;
							break;
						}
						if(item.getType() != null && (MenuEnum.Type.PathAuthorization.index().equals(item.getType())
								|| MenuEnum.Type.ExternalMenu.index().equals(item.getType()))) {
							if (StringTools.isNotBlank(item.getLink()) && item.getLink().equals(menu.getLink())) {
								index = i;
								entity = menu;
								break;
							}
						}
					}

					if (entity == null) {
						//新增
						entity = ClassTools.copy(new Menu(), item);
						entity.setParentId(null);
						if(entity.getPriority() == null){
							entity.setPriority(10);
						}
						entity.setIsLeaf(true);
						if(item.getChildren() != null && item.getChildren().size() > 0){
							entity.setIsLeaf(false);
						}
						entity.setCreateDate(new Date());

						try {
							if(menuDao.insert(entity) > 0){
								item.setId(entity.getId());
								addNewMenu(entity,item.getChildren());
							}
						} catch (SQLException e) {
							log.error(e.getMessage(),e);
						}
					} else {
						menuList.remove(index);

						//检查是否修改
						boolean flag = true;
						if (item.getName().equals(entity.getName())) {
							if (item.getType() == null || item.getType().equals(entity.getType())) {
								if (StringTools.isBlank(item.getPermission()) || item.getPermission().equals(entity.getPermission())) {
									if (StringTools.isBlank(item.getLink()) || item.getLink().equals(entity.getLink())) {
										if (item.getPriority() == null || item.getPriority().equals(entity.getPriority())) {
											flag = false;
										}
									}
								}
							}
						}

						if (flag) {
							try {
								entity = ClassTools.copyNotNull(entity, item);
								menuDao.updateNotNull(entity);
							} catch (SQLException e) {
								log.error(e.getMessage(), e);
							}
						}
						updateMenu(entity,item.getChildren(),canDel);
					}
				}

				//删除不存在
				if (menuList != null && menuList.size() > 0) {
					log.info(menuDao.getJdbcKey()+ "数据库存在多余的根数据，存在的数据：{{0:json}}",menuList);
					if(canDel) {
						for (Menu menu : menuList) {
							delete(menu);
						}
					}
				}
			}else{
				log.info(menuDao.getJdbcKey()+ "数据库不存在根数据，全部新增");
				for (MenuData item : menuData) {
					Menu entity = ClassTools.copy(new Menu(), item);
					entity.setParentId(null);
					if(entity.getPriority() == null){
						entity.setPriority(10);
					}
					entity.setIsLeaf(true);
					if(item.getChildren() != null && item.getChildren().size() > 0){
						entity.setIsLeaf(false);
					}
					entity.setCreateDate(new Date());

					try {
						if(menuDao.insert(entity) > 0){
							item.setId(entity.getId());
							addNewMenu(entity,item.getChildren());
						}
					} catch (SQLException e) {
						log.error(e.getMessage(),e);
					}
				}
			}
		}else{
			log.error("{{0}}数据库同步的菜单配置失败，配置信息未空", menuDao.getJdbcKey());
		}
	}

	private void delete(Menu menu){
		List<Menu> children = this.findAllChild(menu.getId());
		if(children != null && children.size() > 0){
			for(Menu child : children){
				delete(child);
			}
		}

		JdbcSession.begin();
		try {
			if(menuDao.deleteById(menu.getId()) > 0){
				//删除角色关联的菜单
				if(RoleService.self().delByMenuId(menu.getId())) {
					JdbcSession.commit();
					log.info(menuDao.getJdbcKey() + "删除菜单：{{0:json}}", menu);
				}
			}
		} catch (SQLException e) {
			log.error(e.getMessage(),e);
		} finally {
			JdbcSession.end();
		}
	}

	private void addNewMenu(Menu parent,List<MenuData> menuData){
		if(menuData != null && menuData.size() > 0){
			for(MenuData item : menuData){
				Menu entity = ClassTools.copy(new Menu(), item);
				entity.setParentId(parent.getId());
				if(entity.getPriority() == null){
					entity.setPriority(10);
				}
				entity.setIsLeaf(true);
				if(item.getChildren() != null && item.getChildren().size() > 0){
					entity.setIsLeaf(false);
				}
				entity.setCreateDate(new Date());

				try {
					if(menuDao.insert(entity) > 0){
						item.setId(entity.getId());
						addNewMenu(entity,item.getChildren());
					}
				} catch (SQLException e) {
					log.error(e.getMessage(),e);
				}
			}
		}
	}

	public void updateMenu(Menu parent,List<MenuData> menuData,boolean canDel){
		List<Menu> menuList = this.findAllChild(parent.getId());
		if (menuData != null && menuData.size() > 0) {
			if (menuList != null && menuList.size() > 0) {
				log.info(menuDao.getJdbcKey()+ "数据库父节点：{{0}}，数据库子节点数：{{1}}，需要更新的子节点数：{{2}}"
						,parent.getName() + "("+parent.getId()+")",menuList.size(),menuData.size());
				for (MenuData item : menuData) {
					int index = -1;
					Menu entity = null;
					for (int i = 0; i < menuList.size(); i++) {
						Menu menu = menuList.get(i);
						//修改名称或访问路径都可以
						if (item.getName().equals(menu.getName())) {
							index = i;
							entity = menu;
							break;
						}
						if(item.getType() != null && (MenuEnum.Type.PathAuthorization.index().equals(item.getType())
							|| MenuEnum.Type.ExternalMenu.index().equals(item.getType()))) {
							if (StringTools.isNotBlank(item.getLink()) && item.getLink().equals(menu.getLink())) {
								index = i;
								entity = menu;
								break;
							}
						}
					}

					if (entity == null) {
						//新增
						entity = ClassTools.copy(new Menu(), item);
						entity.setParentId(parent.getId());
						if(entity.getPriority() == null){
							entity.setPriority(10);
						}
						entity.setIsLeaf(true);
						if(item.getChildren() != null && item.getChildren().size() > 0){
							entity.setIsLeaf(false);
						}
						entity.setCreateDate(new Date());

						log.info(menuDao.getJdbcKey()+ "数据库父节点：{{0}}，新增菜单：{{1:json}}",parent.getName() + "("+parent.getId()+")",entity);
						try {
							if(menuDao.insert(entity) > 0){
								addNewMenu(entity,item.getChildren());
							}
						} catch (SQLException e) {
							log.error(e.getMessage(),e);
						}
					} else {
						menuList.remove(index);
						//检查是否修改
						boolean flag = true;
						if (item.getName().equals(entity.getName())) {
							if (item.getType() == null || item.getType().equals(entity.getType())) {
								if (StringTools.isBlank(item.getPermission()) || item.getPermission().equals(entity.getPermission())) {
									if (StringTools.isBlank(item.getLink()) || item.getLink().equals(entity.getLink())) {
										if (item.getPriority() == null || item.getPriority().equals(entity.getPriority())) {
											flag = false;
										}
									}
								}
							}
						}
						if (flag) {
							try {
								entity = ClassTools.copyNotNull(entity, item);
								menuDao.updateNotNull(entity);
							} catch (SQLException e) {
								log.error(e.getMessage(), e);
							}
						}
						//递归修改
						updateMenu(entity,item.getChildren(),canDel);
					}
				}

				//删除不存在
				if (menuList != null && menuList.size() > 0) {
					log.info(menuDao.getJdbcKey()+ "数据库存在多余的数据，父节点：{{0}}，存在的数据：{{1:json}}",parent.getName() + "("+parent.getId()+")",menuList);
					if(canDel) {
						for (Menu menu : menuList) {
							delete(menu);
						}
					}
				}
			}else{
				log.info(menuDao.getJdbcKey()+ "数据库不存在数据，全部新增，父节点：{{0}}",parent.getName() + "("+parent.getId()+")");
				for (MenuData item : menuData) {
					Menu entity = ClassTools.copy(new Menu(), item);
					entity.setParentId(parent.getId());
					if(entity.getPriority() == null){
						entity.setPriority(10);
					}
					entity.setIsLeaf(true);
					if(item.getChildren() != null && item.getChildren().size() > 0){
						entity.setIsLeaf(false);
					}
					entity.setCreateDate(new Date());

					try {
						if(menuDao.insert(entity) > 0){
							addNewMenu(entity,item.getChildren());
						}
					} catch (SQLException e) {
						log.error(e.getMessage(),e);
					}
				}
			}
		}else{
			if(menuList != null && menuList.size() > 0) {
				log.info(menuDao.getJdbcKey()+ "数据库存在数据，父节点：{{0}}，存在的数据：{{1:json}}",parent.getName() + "("+parent.getId()+")",menuList);
				if(canDel) {
					for (Menu menu : menuList) {
						delete(menu);
					}
				}
			}
		}
	}

	/**
	 * 导入Excel文件数据
	 * 
	 * @return
	 */
	public boolean importExcel(InputStream inStream) {
		try {
			Workbook wb = WorkbookFactory.create(inStream);
			Sheet sheet = wb.getSheetAt(0);
			int i = sheet.getFirstRowNum() + 1;
			int maxRow = sheet.getLastRowNum();

			Map<Long, Menu> map = new HashMap<Long, Menu>();
			Map<Long, Long> ids = new HashMap<Long, Long>();

			for (; i <= maxRow; i++) {
				Row row = sheet.getRow(i);

				if (row.getLastCellNum() >= 6) {
					Menu entity = new Menu();
					Long id = null;
					Long parentId = null;
					Cell cell0 = row.getCell(0);
					String temp0 = cell0.getStringCellValue();
					if (StringUtils.isNotBlank(temp0)) {
						id = Long.valueOf(temp0);
					} else {
						throw new LogicException("第" + i + "行序号为空");
					}
					// 名称
					Cell cell1 = row.getCell(1);
					String temp1 = cell1.getStringCellValue();
					if (StringUtils.isNotBlank(temp1)) {
						entity.setName(temp1.trim());
					} else {
						throw new LogicException("第" + i + "行名称为空");
					}
					// 链接
					Cell cell2 = row.getCell(2);
					try {
						String temp2 = cell2.getStringCellValue();
						if (StringUtils.isNotBlank(temp2)) {
							entity.setLink(temp2.trim());
						}
					} catch (Exception e) {
						// 忽略
					}
					// 优先级
					Cell cell3 = row.getCell(3);
					try {
						String temp3 = cell3.getStringCellValue();
						if (StringUtils.isNotBlank(temp3)) {
							entity.setPriority(Integer.valueOf(temp3.trim()));
						} else {
							entity.setPriority(10);
						}
					} catch (Exception e) {
						// 忽略
					}
					// 是否子节点
					Cell cell4 = row.getCell(4);
					try {
						String temp4 = cell4.getStringCellValue();
						if (StringUtils.isNotBlank(temp4)) {
							entity.setIsLeaf(Boolean.valueOf(temp4.trim()));
						}
					} catch (Exception e) {
						// 忽略
					}

					// 父节点
					Cell cell5 = row.getCell(5);
					try {
						String temp5 = cell5.getStringCellValue();
						if (StringUtils.isNotBlank(temp5)) {
							parentId = Long.valueOf(temp5.trim());
						}
					} catch (Exception e) {
						// 忽略
					}

					Menu menu = getByParentIdAndName(entity.getParentId(), entity.getName());
					if (menu == null) {
						try {
							if (add(entity)) {
								map.put(id, entity);
								if (parentId != null) {
									ids.put(id, parentId);
								}
							}
						} catch (LogicException e) {
							// 忽略
						}
					} else {
						entity.setId(menu.getId());
						try {
							if (update(entity)) {
								map.put(id, entity);
								if (parentId != null) {
									ids.put(id, parentId);
								}
							}
						} catch (LogicException e) {
							// 忽略
						}
					}
				}
			}
			// 进行树结构关联
			for (Long id : ids.keySet()) {
				Menu parentMenu = map.get(ids.get(id));
				if (parentMenu != null) {
					Menu menu = map.get(id);
					menu.setParentId(parentMenu.getId());
					try {
						update(menu);
					} catch (LogicException e) {
						// 忽略
					}
				}
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 删除所有菜单
	 * 
	 * @return
	 */
	public boolean deleteAll() {
		JdbcSession.begin();
		try {
			List<Menu> menuList = menuDao.findAll();
			if (menuList == null || menuList.size() == 0) {
				return true;
			}
			// 遍历删除角色与菜单的关系表
			for (Menu menu : menuList) {
				RoleService.self().delByMenuId(menu.getId());
			}
			if (menuDao.deleteByCondition(new Conditions()) > 0) {
				JdbcSession.commit();
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcSession.end();
		}
		return false;
	}
}
